home *** CD-ROM | disk | FTP | other *** search
/ Point Programming 1 / PPROG1.ISO / pascal / swag / win-os2.swg / 0011_32bit Protected Mode.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-05-26  |  9.2 KB  |  286 lines

  1. {
  2. >What you *can* do is these things.
  3.  
  4. >1. You can modify the limit of a selector from $0000FFFF to
  5. >   $xxxxFFFF so assembler code can use 32-bit addressing.
  6. >   Note that you may not change the lower 16-bit of the limit
  7. >   field, or else the DPMI server crashes.
  8.  
  9. >2. You can compile a 32-bit assembler procedure into your
  10. >   program.  It just needs a tiny (16 byte) wrapper and must
  11. >   reside in the low 64K of a segment (or else interrupts
  12. >   cannot return correctly).  However, the BP linker does
  13. >   not support 32-bit fixups so there are limits as to what
  14. >   you can put into the assembler code.
  15.  
  16. >3. If you are willing to give up assembler access to BP
  17. >   variables, then you can make a binary image and link
  18. >   that into your program.  Then you can do whatever pleases
  19. >   you in the assembler procedure.
  20.  
  21. >If there is interrest, I could post an example routine showing
  22. >this.
  23.  
  24. Three files are needed: a batch file for assembly, an assembler
  25. file with 32-bit code, and a pascal test program.  The test
  26. program is not supposed to do anything useful.
  27.  
  28. The code is unsupported.  You must know what you're doing.
  29. You'll need the `exe2bin' or `exetobin' utility; you'll need
  30. BP7 (with Turbo Assembler, and you cannot use TP7).  You must
  31. be using Borland's DPMI or some DPMI that supports 32-bit
  32. programs.  Don't even think about running this on a 286.  When
  33. things go wrong it's not my fault.  Don't tell me you know a
  34. better way to get the segment limit, because so do I.
  35.  
  36. Morten Welinder
  37. terra@diku.dk
  38.  
  39. { THE BATCH FILE }
  40. { CUT HERE }
  41. {***************************************************************************}
  42.  
  43. @Echo Off
  44. Tasm /M2 /T /L Test32
  45. If Not Exist Test32.Obj Goto End
  46. Tlink /x test32 >Nul
  47. Exe2bin Test32.Exe Test32.Bin
  48. Rem Del Test32.Exe
  49. Del Test32.Obj
  50. :End
  51.  
  52. { THE ASSEMBLER PROGRAM }
  53. { CUT HERE }
  54. {***************************************************************************}
  55.  
  56. ; ---------------------------------------------------------------------------
  57. ; Example 32 bit program for use with Borland Pascal 7.0
  58. ; ---------------------------------------------------------------------------
  59. Ideal                                  ; (Keep Tasm happy)
  60. P386
  61. Model Use32 Huge,Pascal
  62. Segment Code Use32
  63. Assume  Cs:Code
  64. ; ---------------------------------------------------------------------------
  65. Entry0:  Movzx Eax,[Word Esp]          ; Change the stack frame to 32 bits
  66.          Shr   [Dword Esp],16          ; so [Esp+xxx] works as expected.
  67.          Push  Eax
  68.          Jmp   P0
  69. Align 10h
  70. Entry1:  Movzx Eax,[Word Esp]          ; Aligned 10h for speed.
  71.          Shr   [Dword Esp],16
  72.          Push  Eax
  73.          Jmp   P1
  74. Align 10h
  75. Entry2:  Movzx Eax,[Word Esp]          ; Aligned 10h for speed.
  76.          Shr   [Dword Esp],16
  77.          Push  Eax
  78.          Jmp   P2
  79. ; etc.
  80. ; ---------------------------------------------------------------------------
  81. Align 10h
  82. Proc P0 Far L1:Dword,L2:Dword
  83.          Mov   Eax,[L1]                ; Add the parameters
  84.          Add   Eax,[L2]
  85.  
  86.          Shld  Edx,Eax,16              ; Output is left in Dx:Ax
  87.          Ret
  88. Endp
  89. ; ---------------------------------------------------------------------------
  90. Align 10h
  91. Proc P1 Far
  92.          Push  Ds                      ; Call MsDos from a 32 bit segment
  93.          Mov   Ax,Cs                   ; Never ever perform a software
  94.          Mov   Ds,Ax                   ; interrupt if Ip>=64K!
  95.          Mov   Ah,9
  96.          Mov   Edx,Offset Message
  97.          Int   21h
  98.          Pop   Ds
  99.          Ret
  100.  
  101. Message  Db    'Hello, 32 bit world!',13,10,'$'
  102. Endp
  103. ; ---------------------------------------------------------------------------
  104. Align 10h
  105. Proc P2 Far P:Dword
  106.          Push  Ds
  107.          Xor   Esi,Esi
  108.          Lds   Si,[Small P]
  109.          Mov   Ecx,20000h/4
  110.   @@1:   Mov   [Esi],Esi
  111.          Add   Esi,4
  112.          Loop  @@1
  113.          Pop   Ds
  114.          Ret
  115. Endp
  116. ; ---------------------------------------------------------------------------
  117. Ends
  118. End
  119.  
  120. { THE TEST PROGRAM }
  121. { CUT HERE }
  122. {***************************************************************************}
  123.  
  124. Program   Test;
  125. { ------------------------------------------------------------------------- }
  126. Uses      Winapi, Dos;
  127. { ------------------------------------------------------------------------- }
  128. Const     Dpmi_32BitSegment           = $4000;
  129.  
  130. Type      Dpmi_Descriptor             = Record
  131.             Limit0015                 : Word;
  132.             Base0015                  : Word;
  133.             Base1623                  : Byte;
  134.             Rights                    : Byte;   { 7=Prsnt, 6-5=Dpl, 4=App,  }
  135.                                                 { 3-0=Type                  }
  136.             Rights386                 : Byte;   { 7=Gran, 6=Size32, 5=0,    }
  137.                                                 { 4=Avail, 3-0=Limit1619    }
  138.             Base2431                  : Byte;
  139.             End;
  140.  
  141. Var       Sel      : Word;
  142.           Oldright : Word;
  143.           ProcPtr  : Pointer;
  144.           P1       : Function(L1,L2: LongInt): LongInt;
  145.           P2       : Procedure;
  146.           P3       : Procedure(P: Pointer);
  147.           Fil      : File;
  148.           Data     : Pointer;
  149.           Dsel     : Word;
  150. { ------------------------------------------------------------------------- }
  151. Procedure Dpmi_SetSelectorLimit(Sel: Word; Limit: LongInt); Assembler;
  152. Asm    Mov   Ax,0008H
  153.        Mov   Bx,[Sel]
  154.        Mov   Dx,[Word Ptr Limit]
  155.        Mov   Cx,[Word Ptr Limit+2]
  156.        Int   31H
  157. End;
  158. { ------------------------------------------------------------------------- }
  159. Procedure Dpmi_GetDescriptor(Sel: Word; Var Buffer: Dpmi_Descriptor); Assembler;
  160. Asm    Mov   Ax,000Bh
  161.        Mov   Bx,[Sel]
  162.        Les   Di,[Buffer]
  163.        Int   31H
  164. End;
  165. { ------------------------------------------------------------------------- }
  166. Procedure Dpmi_SetDescriptor(Sel: Word; Var Buffer: Dpmi_Descriptor); Assembler;
  167. Asm    Mov   Ax,000Ch
  168.        Mov   Bx,[Sel]
  169.        Les   Di,[Buffer]
  170.        Int   31H
  171. End;
  172. { ------------------------------------------------------------------------- }
  173. Function  Dpmi_GetAccessRights(Sel: Word): Word; Assembler;
  174. Var       Buffer : Dpmi_Descriptor;
  175. Asm    Mov   Bx,[Sel]
  176.        Push  Bx
  177.        Push  Ss
  178.        Lea   Di,[Buffer]
  179.        Push  Di
  180.        Call  Dpmi_GetDescriptor
  181.        Mov   Ax,[Word Ptr Buffer+5]
  182. End;
  183. { ------------------------------------------------------------------------- }
  184. Procedure Dpmi_SetAccessRights(Sel: Word; Rights: Word); Assembler;
  185. Var       Buffer : Dpmi_Descriptor;
  186. Asm    Mov   Bx,[Sel]
  187.        Lea   Di,[Buffer]
  188.        Push  Bx
  189.        Push  Ss
  190.        Push  Di
  191.        Push  Bx
  192.        Push  Ss
  193.        Push  Di
  194.        Call  Dpmi_GetDescriptor
  195.        Mov   Ax,[Word Ptr Buffer+5]
  196.        And   Ax,8F00h
  197.        Mov   Bx,[Rights]
  198.        And   Bx,50Ffh
  199.        Or    Ax,Bx
  200.        Mov   [Word Ptr Buffer+5],Ax
  201.        Call  Dpmi_SetDescriptor
  202. End;
  203. { ------------------------------------------------------------------------- }
  204. Function  Dpmi_GetSelectorLimit(Sel: Word): LongInt; Assembler;
  205. Var       Buffer : Dpmi_Descriptor;
  206. Asm    Mov   Bx,[Sel]
  207.        Push  Bx
  208.        Push  Ss
  209.        Lea   Di,[Buffer]
  210.        Push  Di
  211.        Call  Dpmi_GetDescriptor
  212.        Mov   Dx,[Word Ptr Buffer+6]
  213.        Mov   Ax,[Word Ptr Buffer]
  214.        Test  Dl,80H
  215.        Je    @@3
  216.        Mov   Bx,Ax
  217.        Mov   Cl,4
  218.        Shr   Bx,Cl
  219.        Mov   Cl,12
  220.        Shl   Dx,Cl
  221.        Shl   Ax,Cl
  222.        Or    Dx,Bx
  223.        Or    Ax,0Fffh
  224.        Jmp   @@2
  225.   @@3: And   Dx,0Fh
  226.        Jmp   @@2
  227.   @@1: Mov   Ax,0
  228.        Mov   Dx,0
  229.   @@2:
  230. End;
  231. { ------------------------------------------------------------------------- }
  232. Function Int2HexN(L: LongInt; N:Integer): String;
  233. Const    Digits : Array[0..15] Of Char = '0123456789ABCDEF';
  234. Var      S : String;
  235. Begin
  236.   S:='';
  237.   While N>0 Do Begin
  238.     S:=Digits[L And $F]+S;
  239.     Dec(N);
  240.     L:=L Shr 4;
  241.   End;
  242.   Int2HexN:=S;
  243. End;
  244. { -------------------------------------------------------------------------- }
  245.  
  246.  
  247. Begin
  248.   Data:=GlobalallocPtr(Gmem_Zeroinit,$20000);
  249.   Dsel:=Seg(Data^);
  250.   Dpmi_SetSelectorLimit(Dsel,$1FFFF);
  251.  
  252.   GetMem(ProcPtr,$4000);
  253.   Assign(Fil,'Test32.Bin');
  254.   Reset(Fil,1);
  255.   BlockRead(Fil,ProcPtr^,FileSize(Fil));
  256.   Close(Fil);
  257.   LongInt(@P1):=(LongInt(ProcPtr)+0*16);
  258.   LongInt(@P2):=(LongInt(ProcPtr)+1*16);
  259.   LongInt(@P3):=(LongInt(ProcPtr)+2*16);
  260.  
  261.   Sel:=Seg(ProcPtr^);
  262.   Oldright:=Dpmi_GetAccessRights(Sel);
  263.   Dpmi_SetAccessRights(Sel,(Oldright Or Dpmi_32BitSegment) And $FFF1+$A);
  264.  
  265.   Writeln('Proc:   ',Int2HexN(Sel,4),':',Int2HexN(Ofs(ProcPtr^),8));
  266.   Writeln('Base:   ',Int2HexN(Getselectorbase(Sel),8));
  267.   Writeln('Limit:  ',Int2HexN(Dpmi_GetSelectorLimit(Sel),8));
  268.   Writeln('Rights: ',Int2HexN(Dpmi_GetAccessRights(Sel),4));
  269.   Writeln;
  270.   Writeln('Data:   ',Int2HexN(Seg(Data^),4),':',Int2HexN(Ofs(Data^),8));
  271.   Writeln('Base:   ',Int2HexN(Getselectorbase(Dsel),8));
  272.   Writeln('Limit:  ',Int2HexN(Dpmi_GetSelectorLimit(Dsel),8));
  273.   Writeln('Rights: ',Int2HexN(Dpmi_GetAccessRights(Dsel),4));
  274.   Writeln;
  275.   Writeln('Ss:Sp:  ',Int2HexN(SSeg,4),':',Int2HexN(SPtr,4));
  276.  
  277.   Writeln('Result: ',Int2HexN(P1($12345678,$87654321),8));
  278.   P2;
  279.   P3(Data);
  280.  
  281.   Dpmi_SetAccessRights(Sel,Oldright);
  282.   Dpmi_SetSelectorLimit(Dsel,$FFFF);
  283.   GlobalfreePtr(Data);
  284. End.
  285.  
  286.